#include <string.h>
#include "gkt_os.h"
#include "gkt_system.h"
#include "gkt_keypad.h"
#include "gkt_fpsensor.h"
#include "gkt_rfid.h"
#include "gkt_door.h"
#include "window_common.h"

#define WINDOW_COMMON_MASKABLE_EVENT_BITS	\
	(((1U << (GKT_EVENT_MAX - GKT_EVENT_MASKABLE)) - 1) << GKT_EVENT_MASKABLE)
#define WINDOW_COMMON_MASKABLE_EVENT_BITS_NK	\
	(WINDOW_COMMON_MASKABLE_EVENT_BITS & (~(1U << GKT_EVENT_KEY)))
void window_common_mask(uint32_t mask_bits)
{
	if (mask_bits & (1U << GKT_EVENT_CARD))
		gkt_event_mask_single(GKT_EVENT_CARD, 0);
	gkt_event_mask(mask_bits);

	if (!(mask_bits & (1U << GKT_EVENT_KEY)))
		gkt_key_mask_partial(0);
	gkt_event_unmask(~mask_bits);
}
void window_common_mask_all(void)
{
	window_common_mask(WINDOW_COMMON_MASKABLE_EVENT_BITS);
}

#define WINDOW_COMMON_ALL_KEYS_MASK	((1U << GKT_KEY_MAX) - 1)
void window_common_mask_except_keys(uint32_t unmask_keys_bits)
{
	uint32_t masked_key_bits;

	gkt_event_mask(WINDOW_COMMON_MASKABLE_EVENT_BITS_NK);

	if (unmask_keys_bits & WINDOW_COMMON_ALL_KEYS_MASK) {
		masked_key_bits = WINDOW_COMMON_ALL_KEYS_MASK & (~unmask_keys_bits);
		gkt_key_mask_partial(masked_key_bits);
		gkt_event_unmask_single(GKT_EVENT_KEY);
	}
	else
		gkt_event_mask_single(GKT_EVENT_KEY, 0);
}

void window_common_mask_except_return(void)
{
	uint32_t unmask_keys_bits;

	unmask_keys_bits = 1U << GKT_KEY_RETURN;
	window_common_mask_except_keys(unmask_keys_bits);
}

void window_common_mask_except_cancel_ok(void)
{
	uint32_t unmask_keys_bits;

	unmask_keys_bits = (1U << GKT_KEY_CANCEL) | (1U << GKT_KEY_OK);
	window_common_mask_except_keys(unmask_keys_bits);
}

void window_common_mask_except_updn_cancel_ok(void)
{
	uint32_t unmask_keys_bits;

	unmask_keys_bits = (1U << GKT_KEY_UP) | (1U << GKT_KEY_DOWN) 
						| (1U << GKT_KEY_CANCEL) | (1U << GKT_KEY_OK);
	window_common_mask_except_keys(unmask_keys_bits);
}
typedef struct _window_common_krt_state {
	uint32_t	depth;
} window_common_krt_state_s;
static window_common_krt_state_s s_window_common_krt_state;

#if defined(GKT_CONFIG_DEBUG_ENABLE) && GKT_CONFIG_DEBUG_ENABLE
void _window_common_control_key_real_trim(const char *prefix, int enable)
{
	gkt_trace("KRT - (%s) enable(%d), depth(%u)\n",
		prefix, enable,	s_window_common_krt_state.depth);

	if (enable) {
		if (s_window_common_krt_state.depth > 0) {
			s_window_common_krt_state.depth--;
			if (!s_window_common_krt_state.depth)
				gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_RESTORE);
		}
		else {
			gkt_error("window_common_control_key_real_trim: underflow!\n");
			GKT_ASSERT(0);
		}
	} else {
		if (!s_window_common_krt_state.depth)
			gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_BACKUP);
		s_window_common_krt_state.depth++;
	}
}
#else
void _window_common_control_key_real_trim(int enable)
{
	gkt_trace("KRT - enable(%d), depth(%u)\n",
		enable, s_window_common_krt_state.depth);

	if (enable) {
		if (s_window_common_krt_state.depth > 0) {
			s_window_common_krt_state.depth--;
			if (!s_window_common_krt_state.depth)
				gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_RESTORE);
		}
		else {
			gkt_error("window_common_control_key_real_trim: underflow!\n");
			GKT_ASSERT(0);
		}
	} else {
		if (!s_window_common_krt_state.depth)
			gkt_keypad_control(GKT_KEYPAD_CTRL_REAL_TRIM, GKT_KEYPAD_REAL_TRIM_BACKUP);
		s_window_common_krt_state.depth++;
	}
}
#endif

void window_common_mask_except_number_repeat_return(
				uint32_t number_end)
{
	uint32_t unmask_keys_bits;

	unmask_keys_bits = (1U << (number_end + 1)) - 1;
	unmask_keys_bits |= 1U << GKT_KEY_RETURN;
	window_common_mask_except_keys(unmask_keys_bits);

#if !defined(GKT_CONFIG_KEY_LED_1TO1) || !GKT_CONFIG_KEY_LED_1TO1
	gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, ~0);
#endif
}
void window_common_mask_except_number_return(uint32_t number_end)
{ 
	uint32_t unmask_keys_bits; 
	
	unmask_keys_bits = (1U << (number_end + 1)) - 1; 
	unmask_keys_bits &= ~(1U << GKT_KEY_0); 
	unmask_keys_bits |= 1U << GKT_KEY_RETURN; 
	window_common_mask_except_keys(unmask_keys_bits);
}

typedef uint32_t (*self_inspect_fn)(void);

static uint32_t window_common_key_self_inspect(void)
{
	uint32_t result;

	gkt_event_unmask_single(GKT_EVENT_KEY);
	result = gkt_key_calibrate(1, GKT_KEYPAD_CALIBRATE_ACTIVE);
	gkt_event_mask_single(GKT_EVENT_KEY, 0);
	
	return result;
}

#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE
static uint32_t window_common_rfid_self_inspect(void)
{
	int key_masked;
	uint32_t result=0;
	uint8_t rfid_type;
	
	gkt_keypad_control(GKT_KEYPAD_CTRL_DISABLE, 0);
	gkt_thread_sleep(100);
	key_masked = gkt_event_is_masked(GKT_EVENT_KEY);
	if (!key_masked)
		gkt_event_mask_single(GKT_EVENT_KEY, GKT_KEY_MASK_F_LED_DETACH);

	gkt_get_rfid_type(&rfid_type);
#if defined(GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018		
	if ((rfid_type == GKT_RFID_CHIP_TYPE_YC5018)
		|| (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF))
#else
	if (gp_window_unreset_data->rfid_standby_mode == GKT_RFID_STANBY_SOFT_POWEROFF)
#endif	
	{	
#if defined(GKT_CONFIG_RFID_YC5018) && GKT_CONFIG_RFID_YC5018		
		/*standby poweroff mode*/
		gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, ~0);
		gkt_event_unmask_single(GKT_EVENT_CARD);
		result = gkt_rfid_self_inspect(1);
		
		uint32_t gain;
		uint32_t water_level;

		gkt_rfid_factory_gain_get(&gain);
		if ((gp_window_unreset_data->yc_rfid_gain != gain) 
			&& (gain != 0)) {
			gp_window_unreset_data->yc_rfid_gain = gain;
			gkt_printf("save card gain =0x%x\n",
				gp_window_unreset_data->yc_rfid_gain);	
			window_data_save();
		}
		
		gkt_rfid_factory_water_level_get(&water_level);
		if ((gp_window_unreset_data->yc_rfid_water_level_factory != water_level) 
			&& (water_level != 0)) {
			gp_window_unreset_data->yc_rfid_water_level_factory = (int)water_level;
			gkt_printf("save card calibrate level=0x%x\n",
					gp_window_unreset_data->yc_rfid_water_level_factory);		
			window_data_save();
		}
		
		gkt_event_mask_single(GKT_EVENT_CARD, 0);
#endif		
	}
	else {/*standby lpcd mode*/
		/*led all off */
		gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, 0);
		gkt_thread_sleep(100);
		
		gkt_event_unmask_single(GKT_EVENT_CARD);
		result = gkt_rfid_self_inspect(0);
		gkt_event_mask_single(GKT_EVENT_CARD, 0);
		if (result == GKT_SUCCESS) {
			/*led all on */
			gkt_key_led_control(GKT_KEY_LED_CTRL_ALL_ON, 0);
			gkt_key_led_control(GKT_KEY_LED_CTRL_BRIGHT, ~0);
			gkt_thread_sleep(100);
			
			gkt_event_unmask_single(GKT_EVENT_CARD);
			result = gkt_rfid_self_inspect(1);
			gkt_event_mask_single(GKT_EVENT_CARD, 0);
		}		
	}

	gkt_keypad_control(GKT_KEYPAD_CTRL_ENABLE, 0);
	if (!key_masked)
		gkt_event_unmask_single(GKT_EVENT_KEY);
	gkt_key_led_control(GKT_KEY_LED_CTRL_ALL_ON, 0);
	
	return result;
}
#endif

typedef struct _self_inspect_item {
	self_inspect_fn	self_inspect;
} self_inspect_item_s;
static self_inspect_item_s s_self_inspect_items[] = {
#if defined(GKT_CONFIG_KEYPAD_ENABLE) && GKT_CONFIG_KEYPAD_ENABLE
	[WINDOW_SELF_INSPECT_KEYPAD] = { window_common_key_self_inspect },
#endif

#if defined(GKT_CONFIG_FPS_ENABLE) && GKT_CONFIG_FPS_ENABLE
	[WINDOW_SELF_INSPECT_FPSENSOR] = { gkt_fpsensor_self_inspect },
#endif

#if defined(GKT_CONFIG_RFID_ENABLE) && GKT_CONFIG_RFID_ENABLE
	[WINDOW_SELF_INSPECT_RFID] = { window_common_rfid_self_inspect }
#endif
};
static uint32_t s_self_inspect_item_nums = sizeof(s_self_inspect_items) / sizeof(self_inspect_item_s);

int window_common_self_inspect(uint32_t error_bits[WINDOW_SELF_INSPECT_MAX])
{
	uint32_t i, retval;
	int failed_nums;

	memset(error_bits, 0, sizeof(uint32_t) * WINDOW_SELF_INSPECT_MAX);

	failed_nums = 0;
	for (i = 0; i < s_self_inspect_item_nums; i++) {
		if (s_self_inspect_items[i].self_inspect) {
			retval = (*s_self_inspect_items[i].self_inspect)();
			if (retval != 0) {
				error_bits[i] = retval;
				failed_nums++;
				gkt_error("self_inspect: (%u) error_bits = 0x%x\n", i, retval);
			}
		}
	}

	return failed_nums;
}

/* door tamper alarm */
#if defined(GKT_CONFIG_DOOR_TAMPER_ENABLE) \
	&& GKT_CONFIG_DOOR_TAMPER_ENABLE
void window_door_tamper_stop(void)
{
	if(g_window_ram_data.door_tamper_detect)
		gkt_door_tamper_stop();
}
#if	defined(GKT_CONFIG_FACE_ID_ENABLE)	&& (GKT_CONFIG_FACE_ID_ENABLE)
#if	defined(GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)	&& (GKT_CONFIG_PROXIMITY_SENSOR_ENABLE)
#include "gkt_pr_sensor.h"
void gkt_pr_sensor_handle(void)
{
	gkt_user_amount_s amount = {0, 0};
	int retval;

	retval = gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX,
					GKT_USER_TYPE_MAX);
	if ((GKT_SUCCESS == retval) && (amount.used_nums == 0)){
		gkt_pr_sensor_set_threshold(gp_window_data->pr_sensor_state);
		g_window_retmem_data.pr_power_state = SENSE_PR_POWER_ON;
	}
	else if((GKT_SUCCESS == retval) && (amount.used_nums > 0)){
		retval = gkt_user_get_amount(&amount, GKT_USER_AUTH_MAX,
								GKT_USER_TYPE_FACE_ID);
		if ((GKT_SUCCESS == retval) && (amount.used_nums == 0)){
			gkt_pr_sensor_set_threshold(SENSE_SHUTDOWN);
			g_window_retmem_data.pr_power_state = SENSE_PR_POWER_OFF;
		}
		else if((GKT_SUCCESS == retval) && (amount.used_nums > 0)){
			gkt_pr_sensor_set_threshold(gp_window_data->pr_sensor_state);
			g_window_retmem_data.pr_power_state = SENSE_PR_POWER_ON;
		}
	}
	else{
		gkt_pr_sensor_set_threshold(SENSE_SHUTDOWN);//err
		g_window_retmem_data.pr_power_state = SENSE_PR_POWER_OFF;
	}
}
#endif
#endif

#endif

